﻿using MicroCloud.Options;

namespace MicroCloud.Entity.MySql
{
    #region "MySql <see cref="DbContextOptionsBuilder"/> 数据库驱动差异处理器"
    /// <summary>
    /// MySql <see cref="DbContextOptionsBuilder"/> 数据库驱动差异处理器
    /// </summary>
    [Dependency(ServiceLifetime.Singleton)]
    public class MySqlDbContextOptionsBuilderDriveHandler : IDbContextOptionsBuilderDriveHandler
    {
        //字段
        private readonly ILogger _logger;
        private readonly ServerVersion _serverVersion;

        #region "属性"
        #region "获取 数据库类型名称"
        /// <summary>
        /// 获取 数据库类型名称，如 SQLSERVER，MYSQL，SQLITE等
        /// </summary>
        public DatabaseType Type { get; } = DatabaseType.MySql;
        #endregion

        #endregion

        #region "构造函数"
        #region "初始化一个 <see cref="MySqlDbContextOptionsBuilderDriveHandler"/> 类型的新实例"
        /// <summary>
        /// 初始化一个 <see cref="MySqlDbContextOptionsBuilderDriveHandler"/> 类型的新实例
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public MySqlDbContextOptionsBuilderDriveHandler(IServiceProvider provider)
        {
            _logger = provider.GetLogger(this);
            _serverVersion = provider.GetService<MySqlServerVersion>() ?? MySqlServerVersion.LatestSupportedServerVersion;
        }
        #endregion

        #endregion

        #region "方法"
        #region "处理 <see cref="DbContextOptionsBuilder"/> 驱动差异"
        /// <summary>
        /// 处理 <see cref="DbContextOptionsBuilder"/> 驱动差异
        /// </summary>
        /// <param name="builder">数据上下文配置构建器</param>
        /// <param name="connectionString">连接字符串</param>
        /// <param name="existingConnection">已存在的连接对象</param>
        /// <param name="dbContextOption">数据上下文配置选项</param>
        /// <returns></returns>
        public virtual DbContextOptionsBuilder Handle(DbContextOptionsBuilder builder, string connectionString, DbConnection existingConnection, DbContextOption dbContextOption)
        {
            DbContextOptionsBuilderAction(builder);
            void action(MySqlDbContextOptionsBuilder b)
            {
                if (!ServiceExtensions.MigrationAssemblyName.IsMissing())
                {
                    b.MigrationsAssembly(ServiceExtensions.MigrationAssemblyName);
                }
                if (dbContextOption.CommandTimeout != null)
                {
                    b.CommandTimeout(dbContextOption.CommandTimeout);
                }
                MySqlDbContextOptionsBuilderAction(b);
            }

            if (existingConnection == null)
            {
                _logger.LogDebug("使用新连接 {connectionString} 应用 MySql 数据库", connectionString);
                builder.UseMySql(connectionString, _serverVersion, action);

            }
            else
            {
                _logger.LogDebug("使用已存在的连接 {connectionString} 应用 MySql 数据库", existingConnection.ConnectionString);
                builder.UseMySql(existingConnection, _serverVersion, action);

            }

            ServiceExtensions.MigrationAssemblyName = null;
            return builder;
        }
        #endregion

        #endregion

        #region "受保护的方法"
        #region "重写以实现 <see cref="MySqlDbContextOptionsBuilder"/> 的自定义行为"
        /// <summary>
        /// 重写以实现 <see cref="MySqlDbContextOptionsBuilder"/> 的自定义行为
        /// </summary>
        /// <param name="options"></param>
        protected virtual void MySqlDbContextOptionsBuilderAction(MySqlDbContextOptionsBuilder options)
        { }
        #endregion
        #region "重写以实现 <see cref="DbContextOptionsBuilder"/> 的自定义行为"
        /// <summary>
        /// 重写以实现 <see cref="DbContextOptionsBuilder"/> 的自定义行为
        /// </summary>
        /// <param name="builder"></param>
        protected virtual void DbContextOptionsBuilderAction(DbContextOptionsBuilder builder)
        { }
        #endregion

        #endregion

    }
    #endregion

}
